﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace Objects
{
    public class Tank : BaseObject
    {
        int PlayerNumber;
        public Texture2D TurretImage;
        float HorizontalMovementSpeed = 200;
        float VerticalMovementSpeed = 200;
        
        public float TurretOrientation = 0;
        float TurretRotationSpeed = 0.25f;
        GamePadState theGamePad;
        float FireTimer = 0;
        float FireRate = 0.5f;
        bool CanFire = true;
        float TriggerDeadZone = 0.1f;
        float LeftThumbstickDeadzone = 0.1f;
        float RightThumbstickDeadzone = 0.1f;
        
        //  Spawn protection members
        bool Dead = false;
        float SpawnProtection = 3f;
        float SpawnTimer = 0;
        float SpawnColorMod = 0;
        Color SpawnColor = Color.White;

        //  Tank Screen Bounds
        float LeftScreenBound = 100;
        float RightScreenBound = 1820;
        float TopScreenBound = 100;
        float BottomScreenBound = 980;

        bool CanMoveRight = true;
        bool CanMoveLeft = true;
        bool CanMoveUp = true;
        bool CanMoveDown = true;

        public Tank(int playerNumber)
        {
            RenderColor = Color.White;
            PlayerNumber = playerNumber;

            if (PlayerNumber == 1)
            {
                Position = new Vector2(100, 150);
                ObjectType = Types.Player1;
            }
            if (PlayerNumber == 2)
            {
                Position = new Vector2(1720, 150);
                ObjectType = Types.Player2;
            }
            if (PlayerNumber == 3)
            {
                Position = new Vector2(100, 860);
                ObjectType = Types.Player3;
            }
            if (PlayerNumber == 4)
            {
                Position = new Vector2(1720, 860);
                ObjectType = Types.Player4;
            }

        }
        public void LoadResources()
        {
            if (PlayerNumber == 1)
            {
                Image = States.GameplayState.theTextureManager.GetTexture("TANK1");
                TurretImage = States.GameplayState.theTextureManager.GetTexture("TANK1TURRET");
            }
            if (PlayerNumber == 2)
            {
                Image = States.GameplayState.theTextureManager.GetTexture("TANK2");
                TurretImage = States.GameplayState.theTextureManager.GetTexture("TANK1TURRE2");
            }
            if (PlayerNumber == 3)
            {
                Image = States.GameplayState.theTextureManager.GetTexture("TANK3");
                TurretImage = States.GameplayState.theTextureManager.GetTexture("TANK3TURRET");
            }
            if (PlayerNumber == 4)
            {
                Image = States.GameplayState.theTextureManager.GetTexture("TANK4");
                TurretImage = States.GameplayState.theTextureManager.GetTexture("TANK4TURRET");
            }
        }
        public void ProcessPlayerOneInput(float ElapsedTime)
        {
            theGamePad = GamePad.GetState(PlayerIndex.One, GamePadDeadZone.Circular);

            if (theGamePad.ThumbSticks.Left.X > LeftThumbstickDeadzone && CanMoveRight == true)
            {
                if (Position.X < RightScreenBound)
                {
                    Position.X += (theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                    
                }
                else
                {
                    Position.X = RightScreenBound + 1; ;
                }

            }
            if (theGamePad.ThumbSticks.Left.X < LeftThumbstickDeadzone && CanMoveLeft == true)
            {
                if (Position.X >= LeftScreenBound)
                {
                    Position.X += +(theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = LeftScreenBound - 1;
                }
            }

            if (theGamePad.ThumbSticks.Left.Y > LeftThumbstickDeadzone && CanMoveDown == true)
            {
                if (Position.Y > TopScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * VerticalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = TopScreenBound - 1;
                }
            }
            if (theGamePad.ThumbSticks.Left.Y < LeftThumbstickDeadzone && CanMoveUp == true)
            {
                if (Position.Y < BottomScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * VerticalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = BottomScreenBound + 1;
                }
            }



            if (theGamePad.ThumbSticks.Left.Length() > LeftThumbstickDeadzone)
                Orientation = (float)Math.Atan2(theGamePad.ThumbSticks.Left.X, theGamePad.ThumbSticks.Left.Y);

            if (theGamePad.ThumbSticks.Right.Length() > RightThumbstickDeadzone)
            {
                float rotation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);

                float difference = WrapAngle(rotation - TurretOrientation);
                difference = MathHelper.Clamp(difference, -TurretRotationSpeed, TurretRotationSpeed);

                TurretOrientation = WrapAngle(TurretOrientation + difference);

                //TurretOrientation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);
            }
            if (theGamePad.Triggers.Right > 0.1f)
                FireBullet(ElapsedTime);
            
        }
        public void ProcessPlayerTwoInput(float ElapsedTime)
        {
           
            theGamePad = GamePad.GetState(PlayerIndex.Two, GamePadDeadZone.Circular);

            if (theGamePad.ThumbSticks.Left.X > LeftThumbstickDeadzone)
            {
                if (Position.X < RightScreenBound)
                {
                    Position.X += (theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = RightScreenBound + 1; ;
                }

            }
            if (theGamePad.ThumbSticks.Left.X < LeftThumbstickDeadzone)
            {
                if (Position.X >= LeftScreenBound)
                {
                    Position.X += +(theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = LeftScreenBound - 1;
                }
            }

            if (theGamePad.ThumbSticks.Left.Y > LeftThumbstickDeadzone)
            {
                if (Position.Y > TopScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = TopScreenBound - 1;
                }
            }
            if (theGamePad.ThumbSticks.Left.Y < LeftThumbstickDeadzone)
            {
                if (Position.Y < BottomScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = BottomScreenBound + 1;
                }
            }



            if (theGamePad.ThumbSticks.Left.Length() > LeftThumbstickDeadzone)
                Orientation = (float)Math.Atan2(theGamePad.ThumbSticks.Left.X, theGamePad.ThumbSticks.Left.Y);

            if (theGamePad.ThumbSticks.Right.Length() > RightThumbstickDeadzone)
            {
                float rotation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);

                float difference = WrapAngle(rotation - TurretOrientation);
                difference = MathHelper.Clamp(difference, -TurretRotationSpeed, TurretRotationSpeed);

                TurretOrientation = WrapAngle(TurretOrientation + difference);

                //TurretOrientation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);
            }
            if (theGamePad.Triggers.Right > 0.1f)
                FireBullet(ElapsedTime);
        }
        public void ProcessPlayerThreeInput(float ElapsedTime)
        {
            theGamePad = GamePad.GetState(PlayerIndex.Three, GamePadDeadZone.Circular);

            if (theGamePad.ThumbSticks.Left.X > LeftThumbstickDeadzone)
            {
                if (Position.X < RightScreenBound)
                {
                    Position.X += (theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = RightScreenBound + 1; ;
                }

            }
            if (theGamePad.ThumbSticks.Left.X < LeftThumbstickDeadzone)
            {
                if (Position.X >= LeftScreenBound)
                {
                    Position.X += +(theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = LeftScreenBound - 1;
                }
            }

            if (theGamePad.ThumbSticks.Left.Y > LeftThumbstickDeadzone)
            {
                if (Position.Y > TopScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = TopScreenBound - 1;
                }
            }
            if (theGamePad.ThumbSticks.Left.Y < LeftThumbstickDeadzone)
            {
                if (Position.Y < BottomScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = BottomScreenBound + 1;
                }
            }



            if (theGamePad.ThumbSticks.Left.Length() > LeftThumbstickDeadzone)
                Orientation = (float)Math.Atan2(theGamePad.ThumbSticks.Left.X, theGamePad.ThumbSticks.Left.Y);

            if (theGamePad.ThumbSticks.Right.Length() > RightThumbstickDeadzone)
            {
                float rotation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);

                float difference = WrapAngle(rotation - TurretOrientation);
                difference = MathHelper.Clamp(difference, -TurretRotationSpeed, TurretRotationSpeed);

                TurretOrientation = WrapAngle(TurretOrientation + difference);

                //TurretOrientation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);
            }
            if (theGamePad.Triggers.Right > 0.1f)
                FireBullet(ElapsedTime);
        }
        public void ProcessPlayerFourInput(float ElapsedTime)
        {
            theGamePad = GamePad.GetState(PlayerIndex.Four, GamePadDeadZone.Circular);

            if (theGamePad.ThumbSticks.Left.X > LeftThumbstickDeadzone)
            {
                if (Position.X < RightScreenBound)
                {
                    Position.X += (theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.X = RightScreenBound + 1; ;
                }

            }
            if (theGamePad.ThumbSticks.Left.X < LeftThumbstickDeadzone)
            {
                if (Position.X >= LeftScreenBound)
                {
                    Position.X += theGamePad.ThumbSticks.Left.X * HorizontalMovementSpeed * ElapsedTime;
                }
                else
                {
                    Position.X = LeftScreenBound - 1;
                    Position.X += theGamePad.ThumbSticks.Left.X * (-HorizontalMovementSpeed) * ElapsedTime;
                }
            }

            if (theGamePad.ThumbSticks.Left.Y > LeftThumbstickDeadzone)
            {
                if (Position.Y > TopScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = TopScreenBound - 1;
                }
            }
            if (theGamePad.ThumbSticks.Left.Y < LeftThumbstickDeadzone)
            {
                if (Position.Y < BottomScreenBound)
                {
                    Position.Y += -(theGamePad.ThumbSticks.Left.Y * HorizontalMovementSpeed) * ElapsedTime;
                }
                else
                {
                    Position.Y = BottomScreenBound + 1;
                }
            }



            if (theGamePad.ThumbSticks.Left.Length() > LeftThumbstickDeadzone)
                Orientation = (float)Math.Atan2(theGamePad.ThumbSticks.Left.X, theGamePad.ThumbSticks.Left.Y);

            if (theGamePad.ThumbSticks.Right.Length() > RightThumbstickDeadzone)
            {
                float rotation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);

                float difference = WrapAngle(rotation - TurretOrientation);
                difference = MathHelper.Clamp(difference, -TurretRotationSpeed, TurretRotationSpeed);

                TurretOrientation = WrapAngle(TurretOrientation + difference);

                //TurretOrientation = (float)Math.Atan2(theGamePad.ThumbSticks.Right.X, theGamePad.ThumbSticks.Right.Y);
            }
            if (theGamePad.Triggers.Right > 0.1f)
                FireBullet(ElapsedTime);
        }
        public void GetInput(float ElapsedTime)
        {
            if (PlayerNumber == 1)
            {
                ProcessPlayerOneInput(ElapsedTime);
            }
            if (PlayerNumber == 2)
            {
                ProcessPlayerTwoInput(ElapsedTime);
            }
            if (PlayerNumber == 3)
            {
                ProcessPlayerThreeInput(ElapsedTime);
            }
            if (PlayerNumber == 4)
            {
                ProcessPlayerFourInput(ElapsedTime);
            }
        }
        public void FireBullet(float ElapsedTime)
        {
            if (CanFire != true)
            {
                FireTimer += ElapsedTime;
                if (FireTimer >= FireRate)
                {
                    CanFire = true;
                    FireTimer = 0;
                }
                
            }
            else
            {
                Objects.Bullet bullet = new Bullet(this);
                States.GameplayState.Instance.theObjectManager.AddObject(bullet);
                CanFire = false;
                Systems.SoundManager.Instance.PlaySound("GunFire1");
                States.GameplayState.Instance.GameSession.AddShots(PlayerNumber);
            }
        }
        public override void Update(float ElapsedTime)
        {
            GetInput(ElapsedTime);
            CheckDamageCollision();
            CheckTankCollisions();
            CollisionRect.X = (int)Position.X;
            CollisionRect.Y = (int)Position.Y;
            if (States.GameplayState.Instance.GameSession.GetTankHealth(PlayerNumber) <= 0)
            {
                States.GameplayState.Instance.GameSession.AddDeaths(PlayerNumber);
                SFX.AnimatedEffects.AnimatedEffectsInstance.PlayExplosion(SFX.AnimatedEffects.EffectType.Explosion, Position);
                Dead = true;
                RespawnTank();
            }

            if (Dead)
            {
                if (Dead)
                {
                    SpawnTimer += ElapsedTime;
                    SpawnColorMod += 15;
                    if (SpawnColorMod >= 150)
                        SpawnColorMod = 0;
                    SpawnColor = new Color(SpawnColorMod, SpawnColorMod, SpawnColorMod, SpawnColorMod);
                }

                if (SpawnTimer >= SpawnProtection)
                {
                    Dead = false;
                    SpawnTimer = 0;
                }
            }
        }
        public override void Render(float ElapsedTime, SpriteBatch theSpriteBatch)
        {
            theSpriteBatch.Draw(Image, Position, null, Dead ? SpawnColor : RenderColor, Orientation, new Vector2(Image.Width * 0.5f, Image.Height * 0.5f), 1.0f, SpriteEffects.None, 0);
            theSpriteBatch.Draw(TurretImage, new Vector2(Position.X, Position.Y), null, Dead ? SpawnColor : RenderColor, TurretOrientation, new Vector2(15, 40), 1.0f, SpriteEffects.None, 0);
        }

        public void RespawnTank()
        {
            Systems.SoundManager.Instance.PlaySound("Explosion1");
            States.GameplayState.Instance.GameSession.RespawnTank(PlayerNumber);
        }
        public void CheckTankCollisions()
        {
           /* if (PlayerNumber == 1)
            {
                List<BaseObject> GameObjects = new List<BaseObject>();
                for (int i = 0; i < States.GameplayState.Instance.theObjectManager.GetObjects().Count; i++)
                {
                    if (States.GameplayState.Instance.theObjectManager.GetObjects()[i].ObjectType == Types.EnvironmentObject)
                        GameObjects.Add(States.GameplayState.Instance.theObjectManager.GetObjects()[i]);
                }

                //GameObjects.Add(States.GameplayState.Instance.GameSession.Player2.PlayerTank);
                //GameObjects.Add(States.GameplayState.Instance.GameSession.Player3.PlayerTank);
                //GameObjects.Add(States.GameplayState.Instance.GameSession.Player4.PlayerTank);

                //for(int ObjectsIterator = 0; ObjectsIterator < GameObjects.Count; ObjectsIterator++)
                //{
                   
                   // if (CollisionRect.Intersects(GameObjects[ObjectsIterator].CollisionRect))
                   // {
                        //// Top facing collision
                        //if (CollisionRect.Top <= GameObjects[ObjectsIterator].CollisionRect.Bottom && CollisionRect.Top > GameObjects[ObjectsIterator].CollisionRect.Top)
                        //{
                        //    CanMoveUp = false;
                        //    break;
                        //}

                        ////  Right facing collision
                        //if (CollisionRect.Right >= GameObjects[ObjectsIterator].CollisionRect.Left && CollisionRect.Right < GameObjects[ObjectsIterator].CollisionRect.Right)
                        //{
                        //  CanMoveRight = false;
                        //  break;
                        //}

                        ////  Left facing collision
                        //if (CollisionRect.Left <= GameObjects[ObjectsIterator].CollisionRect.Right && CollisionRect.Left > GameObjects[ObjectsIterator].CollisionRect.Left)
                        //{
                        //  CanMoveLeft = false;
                        //  break;
                        //}
                    
                        ////  Bottom facing collision
                        //if (CollisionRect.Bottom >= GameObjects[ObjectsIterator].CollisionRect.Top && CollisionRect.Bottom < GameObjects[ObjectsIterator].CollisionRect.Bottom)
                        //{
                        //  CanMoveDown = false;
                        //  break;
                        //}
                        
                       // RenderColor = Color.Black;
                        //break;
                    //}

                    //else
                    //{
                        //CanMoveRight = true;
                        //CanMoveLeft = true;
                        //CanMoveUp = true;
                        //CanMoveDown = true;
                        //RenderColor = Color.White;
                    //}
                //}
               
            }*/
        }
        public void CheckDamageCollision()
        {
            if (!Dead)
            {
                List<Objects.BaseObject> GameObjects = States.GameplayState.Instance.theObjectManager.GetObjects();

                for (int i = 0; i < GameObjects.Count; i++)
                {
                    if (GameObjects[i].ObjectType == Types.Bullet)
                    {
                        if (GameObjects[i].Owner != this)
                        {
                            if (CollisionRect.Intersects(GameObjects[i].CollisionRect))
                            {
                                GameObjects[i].IsActive = false;
                                States.GameplayState.Instance.GameSession.DecreaseHealth(PlayerNumber, 20);
                                Tank SourceDamage = (Tank)GameObjects[i].Owner;
                                States.GameplayState.Instance.GameSession.AddHits(SourceDamage.PlayerNumber);
                                if (States.GameplayState.Instance.GameSession.GetTankHealth(PlayerNumber) <= 0)
                                {
                                    Tank bulletOwner = (Tank)GameObjects[i].Owner;
                                    States.GameplayState.Instance.GameSession.AddKills(bulletOwner.PlayerNumber, 1);
                                }
                            }
                        }
                    }

                    if (GameObjects[i].ObjectType == Types.EnvironmentObject && CollisionRect.Intersects(GameObjects[i].CollisionRect))
                    {

                    }

                }
            }
        }
        
        public override void CheckCollision(BaseObject theObject)
        {

        }
    }
}